`timescale 1ns / 1ps

module ip_fifo(
    input sys_clk_p, //系统输入差分时钟
    input sys_clk_n, //系统输入差分时钟
    input sys_rst_n //系统复位信号
);

//wire define
wire clk_100m ; // 100M 时钟
wire clk_200m ; // 200M 时钟
wire locked ; // 时钟锁定信号
wire rst_n ; // 复位，低有效
wire wr_rst_busy ; // 写复位忙信号
wire rd_rst_busy ; // 读复位忙信号
wire fifo_wr_en ; // FIFO 写使能信号
wire fifo_rd_en ; // FIFO 读使能信号
wire [7:0] fifo_wr_data ; // 写入到 FIFO 的数据
wire [7:0] fifo_rd_data ; // 从 FIFO 读出的数据
wire almost_full ; // FIFO 将满信号
wire almost_empty ; // FIFO 将空信号
wire full ; // FIFO 满信号
wire empty ; // FIFO 空信号
wire [7:0] wr_data_count ; // FIFO 写时钟域的数据计数
wire [7:0] rd_data_count ; // FIFO 读时钟域的数据计数

//*****************************************************
//** main code
//*****************************************************

//通过系统复位信号和时钟锁定信号来产生一个新的复位信号
assign rst_n = sys_rst_n & locked;

//例化 PLL IP 核
clk_wiz_0 clk_wiz_0 (
// Clock out ports
.clk_out1 (clk_100m), // output clk_out1
.clk_out2 (clk_200m), // output clk_out2
// Status and control signals
.locked (locked ), // output locked
// Clock in ports
.clk_in1_p (sys_clk_p), // input clk_in1_p
.clk_in1_n (sys_clk_n) // input clk_in1_n
);

//例化 FIFO IP 核
fifo_generator_0 fifo_generator_0 (
.rst (~rst_n ), // input wire rst
.wr_clk (clk_100m ), // input wire wr_clk
.rd_clk (clk_200m ), // input wire rd_clk
.wr_en (fifo_wr_en ), // input wire wr_en
.rd_en (fifo_rd_en ), // input wire rd_en
.din (fifo_wr_data ), // input wire [7 : 0] din
.dout (fifo_rd_data ), // output wire [7 : 0] dout
.almost_full (almost_full ), // output wire almost_full
.almost_empty (almost_empty ), // output wire almost_empty
.full (full ), // output wire full
.empty (empty ), // output wire empty
.wr_data_count (wr_data_count), // output wire [7 : 0] wr_data_count
.rd_data_count (rd_data_count), // output wire [7 : 0] rd_data_count
.wr_rst_busy (wr_rst_busy ), // output wire wr_rst_busy
.rd_rst_busy (rd_rst_busy ) // output wire rd_rst_busy
);

//例化写 FIFO 模块
fifo_wr u_fifo_wr (
.wr_clk (clk_100m ), // 写时钟
.rst_n (rst_n ), // 复位信号
.wr_rst_busy (wr_rst_busy ), // 写复位忙信号
.fifo_wr_en (fifo_wr_en ), // fifo 写请求
.fifo_wr_data (fifo_wr_data), // 写入 FIFO 的数据
.empty (empty ), // fifo 空信号
.almost_full (almost_full ) // fifo 将满信号
);

//例化读 FIFO 模块
fifo_rd u_fifo_rd (
.rd_clk (clk_200m ), // 读时钟
.rst_n (rst_n ), // 复位信号
.rd_rst_busy (rd_rst_busy ), // 读复位忙信号
.fifo_rd_en (fifo_rd_en ), // fifo 读请求
.fifo_rd_data (fifo_rd_data), // 从 FIFO 输出的数据
.almost_empty (almost_empty), // fifo 将空信号
.full (full ) // fifo 满信号
);

//写时钟域下 ila
ila_0 u_ila_wr (
.clk (clk_100m ), // input wire clk

.probe0 (fifo_wr_en ), // input wire [0:0] probe0
.probe1 (fifo_wr_data ), // input wire [7:0] probe1
.probe2 (almost_full ), // input wire [0:0] probe2
.probe3 (full ), // input wire [0:0] probe3
.probe4 (wr_data_count) // input wire [7:0] probe4
);

//读时钟域下 ila
ila_1 u_ila_rd (
.clk (clk_200m ), // input wire clk

.probe0 (fifo_rd_en ), // input wire [0:0] probe0
.probe1 (fifo_rd_data ), // input wire [7:0] probe1
.probe2 (almost_empty ), // input wire [0:0] probe2
.probe3 (empty ), // input wire [0:0] probe3
.probe4 (rd_data_count) // input wire [7:0] probe4
);

endmodule
